home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / swtools / mipsABI / examples / sup / PORT / step07 / run.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  5.7 KB  |  205 lines

  1. /*
  2.  * Copyright (c) 1991 Carnegie Mellon University
  3.  * All Rights Reserved.
  4.  * 
  5.  * Permission to use, copy, modify and distribute this software and its
  6.  * documentation is hereby granted, provided that both the copyright
  7.  * notice and this permission notice appear in all copies of the
  8.  * software, derivative works or modified versions, and any portions
  9.  * thereof, and that both notices appear in supporting documentation.
  10.  *
  11.  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
  12.  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
  13.  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
  14.  *
  15.  * Carnegie Mellon requests users of this software to return to
  16.  *
  17.  *  Software Distribution Coordinator   or   Software.Distribution@CS.CMU.EDU
  18.  *  School of Computer Science
  19.  *  Carnegie Mellon University
  20.  *  Pittsburgh PA 15213-3890
  21.  *
  22.  * any improvements or extensions that they make and grant Carnegie the rights
  23.  * to redistribute these changes.
  24.  */
  25. /*  run, runv, runp, runvp --  execute process and wait for it to exit
  26.  *
  27.  *  Usage:
  28.  *    i = run (file, arg1, arg2, ..., argn, 0);
  29.  *    i = runv (file, arglist);
  30.  *    i = runp (file, arg1, arg2, ..., argn, 0);
  31.  *    i = runvp (file, arglist);
  32.  *
  33.  *  Run, runv, runp and runvp have argument lists exactly like the
  34.  *  corresponding routines, execl, execv, execlp, execvp.  The run
  35.  *  routines perform a fork, then:
  36.  *  IN THE NEW PROCESS, an execl[p] or execv[p] is performed with the
  37.  *  specified arguments.  The process returns with a -1 code if the
  38.  *  exec was not successful.
  39.  *  IN THE PARENT PROCESS, the signals SIGQUIT and SIGINT are disabled,
  40.  *  the process waits until the newly forked process exits, the
  41.  *  signals are restored to their original status, and the return
  42.  *  status of the process is analyzed.
  43.  *  All run routines return:  -1 if the exec failed or if the child was
  44.  *  terminated abnormally; otherwise, the exit code of the child is
  45.  *  returned.
  46.  *
  47.  **********************************************************************
  48.  * HISTORY
  49.  * $Log: run.c,v $
  50.  * Revision 1.1.1.1  1993/05/21  14:52:17  cgd
  51.  * initial import of CMU's SUP to NetBSD
  52.  *
  53.  * Revision 1.1  89/10/14  19:53:39  rvb
  54.  * Initial revision
  55.  * 
  56.  * Revision 1.2  89/08/03  14:36:46  mja
  57.  *     Update run() and runp() to use <varargs.h>.
  58.  *     [89/04/19            mja]
  59.  * 
  60.  * 23-Sep-86  Glenn Marcy (gm0w) at Carnegie-Mellon University
  61.  *    Merged old runv and runvp modules.
  62.  *
  63.  * 22-Nov-85  Glenn Marcy (gm0w) at Carnegie-Mellon University
  64.  *    Added check and kill if child process was stopped.
  65.  *
  66.  * 30-Apr-85  Steven Shafer (sas) at Carnegie-Mellon University
  67.  *    Adapted for 4.2 BSD UNIX:  Conforms to new signals and wait.
  68.  *
  69.  * 15-July-82 Mike Accetta (mja) and Neal Friedman (naf)
  70.  *                  at Carnegie-Mellon University
  71.  *    Added a return(-1) if vfork fails.  This should only happen
  72.  *    if there are no more processes available.
  73.  *
  74.  * 28-Jan-80  Steven Shafer (sas) at Carnegie-Mellon University
  75.  *    Added setuid and setgid for system programs' use.
  76.  *
  77.  * 21-Jan-80  Steven Shafer (sas) at Carnegie-Mellon University
  78.  *    Changed fork to vfork.
  79.  *
  80.  * 20-Nov-79  Steven Shafer (sas) at Carnegie-Mellon University
  81.  *    Created for VAX.  The proper way to fork-and-execute a system
  82.  *    program is now by "runvp" or "runp", with the program name
  83.  *    (rather than an absolute pathname) as the first argument;
  84.  *    that way, the "PATH" variable in the environment does the right
  85.  *    thing.  Too bad execvp and execlp (hence runvp and runp) don't
  86.  *    accept a pathlist as an explicit argument.
  87.  *
  88.  **********************************************************************
  89.  */
  90.  
  91. #include <stdio.h>
  92. #include <signal.h>
  93. #include <sys/wait.h>
  94. #include <varargs.h>
  95.  
  96. static int dorun();
  97.  
  98. int run (name,va_alist)
  99. char *name;
  100. va_dcl
  101. {
  102.     int val;
  103.     va_list ap;
  104.  
  105.     va_start(ap);
  106.     val = runv (name,ap);
  107.     va_end(ap);
  108.     return(val);
  109. }
  110.  
  111. int runv (name,argv)
  112. char *name,**argv;
  113. {
  114.     return (dorun (name, argv, 0));
  115. }
  116.  
  117. int runp (name,va_alist)
  118. char *name;
  119. va_dcl
  120. {
  121.     int val;
  122.     va_list ap;
  123.  
  124.     va_start(ap);
  125.     val = runvp (name,ap);
  126.     va_end(ap);
  127.     return (val);
  128. }
  129.  
  130. int runvp (name,argv)
  131. char *name,**argv;
  132. {
  133.     return (dorun (name, argv, 1));
  134. }
  135.  
  136. static
  137. int dorun (name,argv,usepath)
  138. char *name,**argv;
  139. int usepath;
  140. {
  141.     int wpid;
  142.     register int pid;
  143. #ifdef _ABI_SOURCE
  144.     struct sigaction ignoresig,intsig,quitsig;
  145. #else
  146.     struct sigvec ignoresig,intsig,quitsig;
  147. #endif
  148.     union wait status;
  149.     int execvp(), execv();
  150.     int (*execrtn)() = usepath ? execvp : execv;
  151.  
  152. #ifdef _ABI_SOURCE
  153.     if ((pid = fork()) == -1)
  154.         return(-1);    /* no more process's, so exit with error */
  155. #else
  156.     if ((pid = vfork()) == -1)
  157.         return(-1);    /* no more process's, so exit with error */
  158. #endif
  159.  
  160.     if (pid == 0) {            /* child process */
  161.         setgid (getgid());
  162.         setuid (getuid());
  163.         (*execrtn) (name,argv);
  164.         fprintf (stderr,"run: can't exec %s\n",name);
  165.         _exit (0377);
  166.     }
  167.  
  168. #ifdef _ABI_SOURCE
  169.     ignoresig.sa_handler = SIG_IGN;    /* ignore INT and QUIT signals */
  170.     sigemptyset (&(ignoresig.sa_mask));
  171.     ignoresig.sa_flags = 0;
  172.     sigaction (SIGINT,&ignoresig,&intsig);
  173.     sigaction (SIGQUIT,&ignoresig,&quitsig);
  174. #else
  175.     ignoresig.sv_handler = SIG_IGN;    /* ignore INT and QUIT signals */
  176.     ignoresig.sv_mask = 0;
  177.     ignoresig.sv_onstack = 0;
  178.     sigvec (SIGINT,&ignoresig,&intsig);
  179.     sigvec (SIGQUIT,&ignoresig,&quitsig);
  180. #endif
  181.     do {
  182. #ifdef _ABI_SOURCE
  183.         wpid = waitpid (pid, &status.w_status, WUNTRACED);
  184. #else
  185.         wpid = wait3 (&status.w_status, WUNTRACED, 0);
  186. #endif
  187.         if (WIFSTOPPED (status)) {
  188.             kill (0,SIGTSTP);
  189.             wpid = 0;
  190.         }
  191.     } while (wpid != pid && wpid != -1);
  192. #ifdef _ABI_SOURCE
  193.     sigaction (SIGINT,&intsig,0);    /* restore signals */
  194.     sigaction (SIGQUIT,&quitsig,0);
  195. #else
  196.     sigvec (SIGINT,&intsig,0);    /* restore signals */
  197.     sigvec (SIGQUIT,&quitsig,0);
  198. #endif
  199.  
  200.     if (WIFSIGNALED (status) || status.w_retcode == 0377)
  201.         return (-1);
  202.  
  203.     return (status.w_retcode);
  204. }
  205.